package xcmg.device.service.agent;

import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.agent.ServiceBorrowInDO;
import xcmg.device.dao.entity.agent.ServiceBorrowInDetailDO;
import xcmg.device.dao.entity.warehouse.WarehouseDO;
import xcmg.device.dao.mapper.MaterialLocationRelationMapper;
import xcmg.device.dao.mapper.agent.ServiceBorrowInDetailMapper;
import xcmg.device.dao.mapper.agent.ServiceBorrowInMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDOMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInboundDetailMapper;
import xcmg.device.infra.CalcUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.vo.agent.ServiceBorrowInAddVO;
import xcmg.device.service.vo.agent.ServiceBorrowInDetailVO;
import xcmg.device.service.vo.agent.ServiceBorrowInVO;
import xcmg.device.service.vo.agent.ServiceBorrowingVO;
import xcmg.device.service.vo.agent.ServiceStaffQuotaUseVO;
import xcmg.device.service.vo.basic.MaterialLocationRelationVO;
import xcmg.device.service.vo.warehouse.WarehouseInboundAddVO;
import xcmg.device.service.vo.warehouse.WarehouseInboundDetailVO;
import xcmg.device.service.vo.warehouse.WarehouseInboundVO;
import xcmg.device.service.warehouse.WarehouseInboundService;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;


/**
 * ServiceBorrowIn 后台接口实现类
 *
 * @author huhuawei
 */
@Service
public class ServiceBorrowInService {
    private static final Logger logger = LoggerFactory.getLogger(ServiceBorrowInService.class);
    @Autowired
    private ServiceBorrowInMapper serviceBorrowInMapper;
    @Autowired
    private WarehouseDOMapper warehouseDOMapper;

    @Autowired
    private FastGenClient fastGenClient;
    @Autowired
    private ServiceBorrowOutService serviceBorrowOutService;
    @Autowired
    private ServiceBorrowInDetailService serviceBorrowInDetailService;
    @Autowired
    private GenDocumentService genDocumentService;
    @Autowired
    private ServiceStaffQuotaService serviceStaffQuotaService;
    @Autowired
    private WarehouseInboundService warehouseInboundService;
    @Autowired
    private ServiceBorrowInDetailMapper serviceBorrowInDetailMapper;
    @Autowired
    private WarehouseInboundDetailMapper warehouseInboundDetailMapper;
    @Autowired
    private ServiceBorrowingService serviceBorrowingService;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private MaterialLocationRelationMapper materialLocationRelationMapper;
    /**
     * 查询列表
     *
     * @param condition
     */
    public PageCommonVO<ServiceBorrowInVO> list(SearchCommonVO<ServiceBorrowInVO> condition, String orgId) {
        if (null == condition.getFilters()) {
            condition.setFilters(new ServiceBorrowInVO());
        }
        ServiceBorrowInVO serviceBorrowInVO = condition.getFilters();
        serviceBorrowInVO.setOrgId(orgId);

        PageCommonVO<ServiceBorrowInVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.orderBy("create_date desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<ServiceBorrowInDO> queryList = serviceBorrowInMapper.queryList(condition.getFilters());
        List<ServiceBorrowInVO> voList = new ArrayList<>();
        for (ServiceBorrowInDO entity : queryList) {
            ServiceBorrowInVO borrowInVO = new ServiceBorrowInVO();
            BeanUtils.copyProperties(entity, borrowInVO);
            voList.add(borrowInVO);
        }
        pageCommonVO.setPageInfo(new PageInfo(queryList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    /**
     * 查询单条记录
     *
     * @param id
     */
    public ServiceBorrowInAddVO queryById(String id,String orgId) {
        ServiceBorrowInAddVO inAddVO = new ServiceBorrowInAddVO();
        ServiceBorrowInDO serviceBorrowInDO = serviceBorrowInMapper.selectByPrimaryKey(id);
        if (null == serviceBorrowInDO) {
            return inAddVO;
        }
        ServiceBorrowInVO vo = new ServiceBorrowInVO();
        BeanUtils.copyProperties(serviceBorrowInDO, vo);
        if (StringUtils.isNotBlank(vo.getWarehouseCode())) {
            WarehouseDO warehouse = warehouseDOMapper.itemByWarehouseCode(orgId, vo.getWarehouseCode());
            if (null != warehouse) {
                vo.setWarehouseCodeDesc(warehouse.getDescription());
            }
        }
        inAddVO.setServiceBorrowInVO(vo);
        ServiceBorrowInDetailVO detailVO = new ServiceBorrowInDetailVO();
        detailVO.setBorrowInId(vo.getId());
        List<ServiceBorrowInDetailDO> borrowInDetailDOList = serviceBorrowInDetailService.queryList(detailVO);
        List<ServiceBorrowInDetailVO> detailVOList = new ArrayList<>();
        for (ServiceBorrowInDetailDO detailDO : borrowInDetailDOList) {
            ServiceBorrowInDetailVO detailVO1 = new ServiceBorrowInDetailVO();
            BeanUtils.copyProperties(detailDO, detailVO1);
            getDefaultLocationCode(orgId, vo, detailVO1);
            detailVOList.add(detailVO1);
        }
        inAddVO.setDetailVOList(detailVOList);
        return inAddVO;
    }

    // 获取默认储位
    private void getDefaultLocationCode(String orgId, ServiceBorrowInVO vo, ServiceBorrowInDetailVO detailVO) {
        MaterialLocationRelationVO condition = new MaterialLocationRelationVO();
        condition.setWarehouseCode(vo.getWarehouseCode());
        condition.setOrgId(orgId);
        condition.setMaterialNo(detailVO.getMaterialsNo());
        List<MaterialLocationRelationVO> voList = materialLocationRelationMapper.list(condition);
        if (!voList.isEmpty()){
            detailVO.setLocationCode(voList.get(0).getLocationCode());
        }
    }

    public ServiceBorrowInDO item(String id) {
        return serviceBorrowInMapper.selectByPrimaryKey(id);
    }

    /**
     * 保存数据
     *
     * @param serviceBorrowInAddVO
     * @param userId
     * @param userName
     * @param orgId
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode save(ServiceBorrowInAddVO serviceBorrowInAddVO, String userId, String userName, String orgId) throws Exception {
        return doSave(serviceBorrowInAddVO, userId, userName, orgId);
    }

    /**
     * 根据状态，等信息保存数据
     *
     * @param serviceBorrowInAddVO
     * @param userId
     * @param userName
     * @param orgId
     */
    private ErrorCode doSave(ServiceBorrowInAddVO serviceBorrowInAddVO, String userId, String userName, String orgId) throws Exception {
        boolean preSaveCheck = preSaveCheck(serviceBorrowInAddVO,orgId);
        if (preSaveCheck) {
            return ErrorCode.IllegalArument;
        }

        String borrowOutNo = serviceBorrowInAddVO.getServiceBorrowInVO().getBorrowOutNo();
        //校验转销售转退回数量
        List<ServiceBorrowInDetailVO> borrowInDetailVOList = serviceBorrowInAddVO.getDetailVOList();
        for (ServiceBorrowInDetailVO serviceBorrowInDetailVO: borrowInDetailVOList) {
            BigDecimal returnQty = serviceBorrowInDetailVO.getReturnQty();
            String materialsNo = serviceBorrowInDetailVO.getMaterialsNo();
            BigDecimal remainingQty = serviceBorrowOutService.getRemainingQty(borrowOutNo, materialsNo, orgId);
            BigDecimal tempReturnQty  = BigDecimal.ZERO;
            if (StringUtils.isNotBlank(serviceBorrowInDetailVO.getId())){
                ServiceBorrowInDetailDO serviceBorrowInDetailDO = serviceBorrowInDetailMapper.selectByPrimaryKey(serviceBorrowInDetailVO.getId());
                tempReturnQty = serviceBorrowInDetailDO.getReturnQty();
            }
            if (null == remainingQty || returnQty.compareTo(remainingQty.add(tempReturnQty)) > 0){
               throw new Exception("提交数量不允许大于可转退回数量");
            }
        }

        ServiceBorrowInDO serviceBorrowInDO = new ServiceBorrowInDO();
        BeanUtils.copyProperties(serviceBorrowInAddVO.getServiceBorrowInVO(), serviceBorrowInDO);
        String borrowInId;
        boolean isAdd = false;
        if (StringUtils.isBlank(serviceBorrowInDO.getId())) {
            String id = fastGenClient.textGuid().getValue();
            if (StringUtils.isBlank(id)) {
                return ErrorCode.IllegalArument;
            }
            isAdd = true;
            borrowInId = id;
            serviceBorrowInDO.setCreateId(userId);
            serviceBorrowInDO.setCreateName(userName);
            serviceBorrowInDO.setCreateDate(new Date());
            serviceBorrowInDO.setId(borrowInId);
            serviceBorrowInDO.setOrgId(orgId);
            // 0-未入库，1-部分入库，2-已入库，3-结单
            //新增的时候需要保存状态
            serviceBorrowInDO.setStatus(0);
            serviceBorrowInDO.setBorrowInNo(genDocumentService.genDocumentNo(BillDesc.ServiceBorrowIn, orgId));
            logger.info("新增操作，serviceBorrowOutDO:{}", serviceBorrowInDO);
        } else {
            borrowInId = serviceBorrowInDO.getId();
            serviceBorrowInDO.setUpdateDate(new Date());
            serviceBorrowInDO.setUpdateId(userId);
            logger.info("编辑操作，serviceBorrowOutDO:{}", serviceBorrowInDO);
        }

        //调用详情表的保存逻辑
        List<ServiceBorrowInDetailVO> detailVOList = serviceBorrowInAddVO.getDetailVOList();
        ServiceBorrowInDetailVO detailVO = new ServiceBorrowInDetailVO();
        detailVO.setBorrowInId(borrowInId);

        List<ServiceBorrowInDetailDO> dbDetails = serviceBorrowInDetailService.queryList(detailVO);
        int seqNo = 0;
        BigDecimal totalPrice = BigDecimal.ZERO;

        for (ServiceBorrowInDetailVO inDetailVO : detailVOList) {
            totalPrice = totalPrice.add(CalcUtil.multiply(inDetailVO.getReturnQty(), inDetailVO.getPrice()));
            ++seqNo;
            if (StringUtils.isEmpty(inDetailVO.getId())) {
                inDetailVO.setSeqNo(seqNo);
            }
            //设置主表的ID
            inDetailVO.setBorrowInId(borrowInId);
            inDetailVO.setBorrowInNo(serviceBorrowInDO.getBorrowInNo());
            if (!isAdd) {
                int status = inDetailVO.getStatus();
                if (3 != status) {
                    //将页面的借用数量与数据库该记录的已出库数量比较
                    Optional<ServiceBorrowInDetailDO> optionalDetailDO = dbDetails.stream().filter(x -> x.getId().equals(inDetailVO.getId())).findFirst();
                    if (optionalDetailDO.isPresent()) {
                        if (inDetailVO.getReturnQty().compareTo(optionalDetailDO.get().getThisReturnQty()) > 0) {
                            if (optionalDetailDO.get().getThisReturnQty().compareTo(BigDecimal.ZERO) == 0) {
                                inDetailVO.setStatus(0);
                            } else {
                                inDetailVO.setStatus(1);
                            }
                        } else {
                            inDetailVO.setStatus(2);
                        }
                    }
                } else {
                    inDetailVO.setStatus(3);
                }
            }
            ErrorCode errorCode = serviceBorrowInDetailService.save(inDetailVO, userId, userName, orgId);
            if (errorCode.getCode() != 0) {
                throw new Exception(errorCode.getDesc());
            }
        }

        serviceBorrowInDO.setTotalPrice(totalPrice);
        boolean isSuccess = this.merge(serviceBorrowInDO) > 0;
        if (!isSuccess) {
            return ErrorCode.Failure;
        }

        //  调用入库的相关逻辑
        if (isAdd) {
            return saveWarehouseInByBorrowInfo(serviceBorrowInDO, detailVOList, userId, orgId);
        }

        ErrorCode errorCode = delBorrowInDetail(serviceBorrowInAddVO, orgId);
        if (errorCode != null) {
            return errorCode;
        }

        return ErrorCode.Success;
    }

    private ErrorCode delBorrowInDetail(ServiceBorrowInAddVO serviceBorrowInAddVO, String orgId) throws Exception {
        List<String> deleteIdList = serviceBorrowInAddVO.getDeleteIdList();
        if (null == deleteIdList || deleteIdList.isEmpty()) {
            return null;
        }
        return serviceBorrowInDetailService.deleteDetails(deleteIdList, orgId);
    }

    private ErrorCode saveWarehouseInByBorrowInfo(ServiceBorrowInDO serviceBorrowInDO, List<ServiceBorrowInDetailVO> detailVOList, String userId, String orgId) throws Exception {
        //非正常出库添加到出库单
        WarehouseInboundVO inboundVO = new WarehouseInboundVO();
        List<WarehouseInboundDetailVO> detailList = new ArrayList<>();
        inboundVO.setBusinessSingle(serviceBorrowInDO.getBorrowInNo().substring(0, 4));
        inboundVO.setBusinessOrder(serviceBorrowInDO.getBorrowInNo());
        inboundVO.setWarehouseCode(serviceBorrowInDO.getWarehouseCode());

        if (ListUtil.isNullOrEmpty(detailVOList)) {
            return ErrorCode.IllegalArument;
        }
        BigDecimal num = BigDecimal.ZERO;
        WarehouseInboundDetailVO detail;
        for (ServiceBorrowInDetailVO inDetailVO : detailVOList) {
            detail = new WarehouseInboundDetailVO();
            detail.setBusinessSingle(inboundVO.getBusinessSingle());
            detail.setBusinessOrder(inboundVO.getBusinessOrder());
            detail.setMaterialNo(inDetailVO.getMaterialsNo());
            detail.setMaterialName(inDetailVO.getMaterialsDes());
            detail.setUnit(inDetailVO.getUnit());
            detail.setAmount(inDetailVO.getReturnQty());
            detail.setRealAmount(BigDecimal.ZERO);
            detail.setTotalPrice(inDetailVO.getReturnQty().multiply(inDetailVO.getPrice()));
            num = num.add(inDetailVO.getReturnQty());
            detailList.add(detail);
        }
        inboundVO.setAmount(num);
        WarehouseInboundAddVO inboundAddVO = new WarehouseInboundAddVO();
        inboundAddVO.setHeaderInfo(inboundVO);
        inboundAddVO.setDetailList(detailList);
        return warehouseInboundService.add(inboundAddVO, userId, orgId);
    }

    /**
     * 保存前信息校验
     */
    private boolean preSaveCheck(ServiceBorrowInAddVO serviceBorrowInAddVO,String orgId) throws Exception {
        if (null == serviceBorrowInAddVO ||
                null == serviceBorrowInAddVO.getServiceBorrowInVO() ||
                null == serviceBorrowInAddVO.getDetailVOList() ||
                serviceBorrowInAddVO.getDetailVOList().isEmpty()) {
            return true;
        }
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    public int merge(ServiceBorrowInDO dto) {
        return serviceBorrowInMapper.merge(dto);
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode delete(String id, String orgId) throws Exception {
        //先判断当前出库状态是否可以删除
        //0-未入库，1-部分入库，2-已入库，3-结单
        ServiceBorrowInDO serviceBorrowInDO = this.item(id);
        if (null == serviceBorrowInDO || (null != serviceBorrowInDO.getStatus() && serviceBorrowInDO.getStatus() != 0)) {
            throw new Exception(ErrorCode.ServiceBorrowOutInfoStatusIsFalseReturn.getDesc());
        }

        //删除借用单信息
        int i = serviceBorrowInMapper.deleteByPrimaryKeySelective(id);
        if (i == 0) {
            throw new Exception(ErrorCode.Failure.getDesc());
        }
        deleteDetails(id, serviceBorrowInDO.getBorrowInNo(), orgId);
        return ErrorCode.Success;
    }

    /**
     * 根据借用单信息删除借用出库单详情信息
     *
     * @param id
     * @throws Exception
     */
    private void deleteDetails(String id, String borrowInNo, String orgId) throws Exception {
        //查询借用单详情信息
        ServiceBorrowInDetailVO vo = new ServiceBorrowInDetailVO();
        vo.setBorrowInId(id);
        List<ServiceBorrowInDetailDO> inDetailDOList = serviceBorrowInDetailService.queryList(vo);
        List<String> detailIds = new ArrayList<>();
        for (ServiceBorrowInDetailDO detailDO : inDetailDOList) {
            detailIds.add(detailDO.getId());
        }
        //删除借用单详情信息
        ErrorCode errorCode = serviceBorrowInDetailService.batchDelete(detailIds);
        //删除事物
        List<String> borrowInNoList = new ArrayList<>();
        borrowInNoList.add(borrowInNo);
        ErrorCode error = warehouseInboundService.removeByBusinessOrders(borrowInNoList, orgId);
        if (ErrorCode.Success != error) {
            throw new Exception(error.getDesc());
        }
    }

    public ServiceBorrowInAddVO borrowingData(String borrowOutNo, String orgId, String userId, String userName) {
        return serviceBorrowOutService.queryByBorrowOutNo(borrowOutNo, orgId, userId, userName);
    }

    /**
     * 手动完成单据<br>
     * materialsNo 不为null,则更改该单据下的零件状态为“手动完成”状态；如果materialsNo为空，则更改整个单据为“手动完成”状态
     *
     * @param billNo      String 单据编号
     * @param materialsNo String 零件编号
     * @param orgId       String 企业ID
     * @return ErrorCode 返回码
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode manualFinish(String billNo, String materialsNo, String orgId) throws Exception {
        ServiceBorrowInDO serviceBorrowInDO = serviceBorrowInMapper.selectByBorrowInNo(billNo);
        updateRollBackQtyLogic(materialsNo, serviceBorrowInDO);
        //零件编码为空，更新单据状态为“手动完成”
        if (StringUtil.isNullOrEmpty(materialsNo)) {
            //借用单结单
            serviceBorrowInDO.setStatus(3);
            serviceBorrowInMapper.updateByPrimaryKeySelective(serviceBorrowInDO);
            warehouseInboundService.updateState(billNo, 3, orgId);
            serviceBorrowInDetailMapper.updateStatus(3, serviceBorrowInDO.getId(), materialsNo);
            warehouseInboundDetailMapper.updateAllStatus(3, billNo, orgId);
        } else {
            serviceBorrowInDetailMapper.updateStatus(3, serviceBorrowInDO.getId(), materialsNo);
            warehouseInboundService.updateDetailState(billNo, materialsNo, null, 3, orgId);
            ErrorCode errorCode = checkBillFinished(serviceBorrowInDO, orgId);

            if (ErrorCode.Success != errorCode) {
                throw new Exception("更新失败");
            }
        }

        return ErrorCode.Success;
    }

    /**
     * 更新退回数量逻辑
     */
    private void updateRollBackQtyLogic(String materialsNo, ServiceBorrowInDO serviceBorrowInDO) throws Exception {
        ServiceBorrowInDetailVO condition = new ServiceBorrowInDetailVO();
        condition.setBorrowInId(serviceBorrowInDO.getId());
        condition.setMaterialsNo(materialsNo);
        List<ServiceBorrowInDetailDO> borrowInDetailDOList = serviceBorrowInDetailMapper.queryList(condition);
        for (ServiceBorrowInDetailDO serviceBorrowInDetailDO : borrowInDetailDOList) {
            Integer status = serviceBorrowInDetailDO.getStatus();
            if (3 == status) {
                continue;
            }
            String borrowOutDetailId = serviceBorrowInDetailDO.getBorrowOutDetailId();
            BigDecimal returnQty = serviceBorrowInDetailDO.getReturnQty();
            BigDecimal thisReturnQty = serviceBorrowInDetailDO.getThisReturnQty() == null ? BigDecimal.ZERO : serviceBorrowInDetailDO.getThisReturnQty();
            //结单之后需要更新相应的借用单数量
            boolean updateResult = serviceBorrowOutService.updateRollBackQty(borrowOutDetailId, BigDecimal.ZERO, returnQty.subtract(thisReturnQty));
            if (!updateResult) {
                throw new Exception("更新借用单退回数量失败");
            }
        }
    }

    /**
     * 校验单据是否已完成<br>
     * 判断单据下的所有零件是否已经完成，如果都完成，则更改单据状态为完成
     *
     * @param serviceBorrowInDO selectByBorrowN
     * @param orgId             String
     * @return Boolean
     */
    private ErrorCode checkBillFinished(ServiceBorrowInDO serviceBorrowInDO, String orgId) throws Exception {
        ServiceBorrowInDetailVO condition = new ServiceBorrowInDetailVO();
        condition.setBorrowInId(serviceBorrowInDO.getId());
        List<ServiceBorrowInDetailDO> inDetailDOList = serviceBorrowInDetailMapper.queryList(condition);
        if (ListUtil.isNullOrEmpty(inDetailDOList)) {
            throw new Exception("未查询到服务借用单详情列表信息");
        }
        boolean manul = false;
        boolean flag = true;
        int status;
        for (ServiceBorrowInDetailDO temp : inDetailDOList) {
            if (temp.getStatus() == 3) {
                manul = true;
            }
            if (2 == temp.getStatus() || 3 == temp.getStatus()) {
                //完成状态
                continue;
            }
            flag = false;
        }
        if (flag) {
            if (manul) {
                status = 3;
            } else {
                status = 2;
            }
        } else {
            status = 1;
        }
        //借用单结单
        ServiceBorrowInDO bean = new ServiceBorrowInDO();
        bean.setId(serviceBorrowInDO.getId());
        bean.setStatus(status);
        serviceBorrowInMapper.updateByPrimaryKeySelective(bean);
        warehouseInboundService.updateState(serviceBorrowInDO.getBorrowInNo(), status, orgId);
        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateByInbound(String borrowInNo, String materialNo, BigDecimal realAmount, Integer singelState, Integer totalState, String orgId) throws Exception {
        ServiceBorrowInDO serviceBorrowInDO = serviceBorrowInMapper.selectByBorrowInNo(borrowInNo);
        if (null == serviceBorrowInDO) {
            throw new Exception("未找到单据记录");
        }
        ServiceBorrowInDO inStatusDO = new ServiceBorrowInDO();
        inStatusDO.setId(serviceBorrowInDO.getId());
        inStatusDO.setStatus(totalState);
        boolean success = serviceBorrowInMapper.updateByPrimaryKeySelective(inStatusDO) > 0;

        if (success) {
            ServiceBorrowInDetailDO inDetailDO = serviceBorrowInDetailMapper.item(serviceBorrowInDO.getId(), materialNo);
            if (null == inDetailDO) {
                throw new Exception("未找到详情记录");
            }

            if (realAmount.compareTo(inDetailDO.getReturnQty()) > 0) {
                throw new Exception("实际入库数量不能大于退回入库数量");
            }

            inDetailDO.setThisReturnQty(realAmount);
            inDetailDO.setStatus(singelState);
            BigDecimal borrowReturnQty = inDetailDO.getBorrowReturnQty() == null ? BigDecimal.ZERO : inDetailDO.getBorrowReturnQty();
            inDetailDO.setBorrowReturnQty(realAmount.add(borrowReturnQty));
            success = serviceBorrowInDetailMapper.updateByPrimaryKeySelective(inDetailDO) > 0;

            //更新借款额度
            ErrorCode errorCode = upUseQuota(realAmount, serviceBorrowInDO, inDetailDO);
            if (ErrorCode.Success != errorCode) {
                throw new Exception(errorCode.getDesc());
            }

            if (success) {
                //减少个人出库零件信息
                ServiceBorrowingVO serviceBorrowingVO = new ServiceBorrowingVO();
                serviceBorrowingVO.setOrgId(orgId);
                serviceBorrowingVO.setUserId(serviceBorrowInDO.getServiceStaffId());
                serviceBorrowingVO.setUserName(serviceBorrowInDO.getServiceStaffName());
                serviceBorrowingVO.setMaterialsNo(inDetailDO.getMaterialsNo());
                serviceBorrowingVO.setMaterialsDes(inDetailDO.getMaterialsDes());
                serviceBorrowingVO.setUnit(inDetailDO.getUnit());
                serviceBorrowingVO.setPrice(inDetailDO.getPrice());
                serviceBorrowingVO.setQuantity(CalcUtil.subtract(BigDecimal.ZERO, realAmount));
                success = serviceBorrowingService.save(serviceBorrowingVO).equals(ErrorCode.Success);
            }
        }

        return success;
    }

    private ErrorCode upUseQuota(BigDecimal realAmount, ServiceBorrowInDO serviceBorrowInDO, ServiceBorrowInDetailDO inDetailDO) throws Exception {
        ServiceStaffQuotaUseVO serviceStaffQuotaUseVO = new ServiceStaffQuotaUseVO();
        serviceStaffQuotaUseVO.setStaffId(serviceBorrowInDO.getServiceStaffId());
        serviceStaffQuotaUseVO.setBorrowedAmount(CalcUtil.subtract(BigDecimal.ZERO, CalcUtil.multiply(inDetailDO.getPrice(), realAmount)));
        return serviceStaffQuotaService.useQuota(serviceStaffQuotaUseVO);
    }

    public void export(List<String> ids) throws Exception {
        List<ServiceBorrowInDO> voList = new ArrayList<>();
        for (String id : ids) {
            ServiceBorrowInDO serviceBorrowInDO = serviceBorrowInMapper.selectByPrimaryKey(id);
            voList.add(serviceBorrowInDO);
        }
        invokeExport(voList);
    }

    public void exportAll(ServiceBorrowInVO condition) throws Exception {
        //PageHelperPlus.startPage(0, 0, "id desc");
        List<ServiceBorrowInDO> doList = serviceBorrowInMapper.queryList(condition);
        invokeExport(doList);
    }

    private void invokeExport(List<ServiceBorrowInDO> voList) throws Exception {
        String title = "借用退回数据导出";
        String[] rowsName = new String[]{"序号", "退回单号", "制单人", "制单时间", "借用单号", "服务人员", "退回仓库", "退回单状态", "备注",
                "零件编码", "零件名称", "单位", "本单已退回", "退回数量", "借用单出库数量", "转销售数量", "借用单已退回", "单价"};
        List<Object[]> dataList = new ArrayList<>();
        Object[] objs;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < voList.size(); i++) {
            ServiceBorrowInDO serviceBorrowInDO = voList.get(i);
            ServiceBorrowInDetailVO condition = new ServiceBorrowInDetailVO();
            condition.setBorrowInId(serviceBorrowInDO.getId());
            List<ServiceBorrowInDetailDO> detailDOList = serviceBorrowInDetailMapper.queryList(condition);
            for (ServiceBorrowInDetailDO detailDO : detailDOList) {
                objs = new Object[rowsName.length];
                objs[0] = i + 1;
                objs[1] = serviceBorrowInDO.getBorrowInNo();
                objs[2] = serviceBorrowInDO.getCreateName();
                objs[3] = sdf.format(serviceBorrowInDO.getCreateDate());
                objs[4] = serviceBorrowInDO.getBorrowOutNo();
                objs[5] = serviceBorrowInDO.getServiceStaffName();
                objs[6] = serviceBorrowInDO.getWarehouseCode();
                objs[7] = getStatusDesc(serviceBorrowInDO.getStatus());
                objs[8] = serviceBorrowInDO.getRemark();
                objs[9] = detailDO.getMaterialsNo();
                objs[10] = detailDO.getMaterialsDes();
                objs[11] = detailDO.getUnit();
                objs[12] = detailDO.getThisReturnQty();
                objs[13] = detailDO.getReturnQty();
                objs[14] = detailDO.getBorrowOutboundQty();
                objs[15] = detailDO.getResaleQty();
                objs[16] = detailDO.getBorrowReturnQty();
                objs[17] = detailDO.getPrice();
                dataList.add(objs);
            }
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private String getStatusDesc(Integer status) {
        switch (status) {
            case 0:
            default:
                return "未入库";
            case 1:
                return "部分入库";
            case 2:
                return "已入库";
            case 3:
                return "强制结单";
        }

    }
}
